/**
 * @copyright Copyright (c) 2023..
 *
 * @file    data_cache.h
 * @brief   描述 文件缓存
 * @author  HC(202206728@any3.com)
 * @version 1.0
 * @date    2023-09-27
 */

#ifndef DATA_CACHE_H
#define DATA_CACHE_H

#include <vector>
#include <unordered_map>
#include <mutex>

#include "eventcommand.h"
#include "data_structure.h"
#include "data_record.h"
#include "timer.hpp"
#include "adr_component.h"
#include "encode_srv.pb.h"

using namespace std;
namespace DcAdr
{
    class DataCache : public EventCommand
    {
    public:
        static DataCache &getInstance();
        void setPublishHandle(adr_component *component);

        //从数据接收，将数据存到缓存
        void addData(ProtoData data);
        void addData(std::vector<ProtoData> &data);

        void processData(const ProtoData &data);

        //设置topic数据有效时长
        void setTopicDataInvildTime(const std::string &topic, const double &beforTime, const double &afterTime);

        //获取topic数据有效时长
        ProtoValidTime getTopicDataInvildTime(const std::string &topic);

        void dealSentryEvent(TriggerEventInfo &trigger, bool &bIgnore);

        //触发trigger,请求数据缓存上云
        void acquireDataToSave(TriggerEventInfo &trigger);

        //获取事件前数据存储
        void getBufferDataToSave(const TriggerEventInfo &trigger);
        void getBufferDataToSaveNolock(const TriggerEventInfo &trigger);

        //判断事件是否结束
        void checkTriggerEventEnd();
        void endEvent(string eventCode);

        //获取topic最新的数据
        ProtoData getLastDataByTopic(const std::string &topic);
        void checkPictureDataTimeValid(const std::string &topic,const ProtoData &data);
        bool JudgeIsIFrame(std::string &topic, EncodeSrv::EncodeH265 &enc,std::map<std::string, bool> &isIframeMap);
        void getAndrEnvirAgain();
    private:
        DataCache();
        ~DataCache();
        //检查数据时间是否有效
        void checkDataTimeValid();

        void timeOut();

        void doSBtest();
        void doNeiCunTest();
		void FindVedioFirstIFrame(std::map<std::string, std::vector<ProtoData>> &pieceData, 
		std::map<std::string, bool> &isIframeMap, double beforeTime, double endTime, const std::string topicname);

    private:
        std::mutex m_mutex;

        // 以下变量需要加锁保护
        PieceProtoData m_dataCache;                            //缓存数据<topic,<时间戳，数据>>
        std::map<std::string,TopicToPictureData> m_pictureDataCacheMap;//图片数据缓存<topic,<时间,数据>>
        std::map<std::string, ProtoValidTime> m_dataViledTime; //有效时长 <topic,时长>
        std::map<std::string, TriggerEventInfo> m_eventPool;   //事件池
        uint32_t m_maxFrame{1000000};                          //缓存帧数上限
        std::map<std::string, ProtoData> m_lastTopicData;      //缓存每个topic最新的数据，以便条件判断
        Timer *m_timer{nullptr};                               //定时器
        Timer *m_timer_2{nullptr};                             //定时器

        std::mutex m_receiveDataMutex;
        std::vector<ProtoData> m_receiveData;                  //订阅消息缓冲池


        // 以下变量不需要加锁保护
        int m_lastInterlTime = 0;
        int m_lastReuploadTime = 0;
        int m_EvtReupTime = 0;
        int m_lastChunkTime = 0;
        int m_getAndrEnvirTime =0;
        int m_malloc_trim=0;
        adr_component *m_component{nullptr};
    };
}

#endif // DATA_CACHE_H
